home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
QuickTime 1.0 for Developers
/
QuickTime 1.0 for Developers.iso
/
Programming Stuff
/
Sample Code
/
MiniEdit
/
Mini Edit Movie Stuff.c
< prev
next >
Wrap
C/C++ Source or Header
|
1991-09-11
|
15KB
|
529 lines
/**************************************************
*
* Moov stuff
*
*
***************************************************/
#include "Mini Edit.h"
#include "Movies.h"
extern MovieInstance movieList[];
/**************************************************
*
* Globals
*
***************************************************/
/* Info about the movie */
MovieInstance *activeMovie; /* The frontmost movie */
short numOpenMovies; /* The number of open movies */
short checkMovieControllerCount; /* Filter proc uses this instead of rescanning movie list */
short theModifiers; /* Modifiers from the event record for MovieController filter */
OSErr theErr; /* Easier than declaring it everywhere */
/**************************************************
*
* SetUpMovies() Initializes the movie tools
*
***************************************************/
void SetUpMovies()
{
short movieCount;
theErr = EnterMovies(); /* This would normally with the other manager inits */
if (theErr)
DebugStr((StringPtr)"\pEnterMovies Failed");
/* Clear the array of open movies */
for (movieCount = 0;movieCount<maxMovies;movieCount++)
movieList[movieCount].movie = 0;
activeMovie = 0;
numOpenMovies = 0; /* None currently open */
}
/**************************************************
*
* GetAvailMovie()
* Returns a pointer to an unused element in movieList
* or 0 if none available
*
***************************************************/
MovieInstance* GetAvailMovie()
{
short movieCount;
/* Loop through looking for a match */
for (movieCount = 0;movieCount<maxMovies;movieCount++)
if (movieList[movieCount].movie==0)
break;
if (movieCount < maxMovies)
return(&movieList[movieCount]);
return(0L);
}
/**************************************************
*
* CleanUpMovie(theMovie) Throws out the movie, window, and controller
*
***************************************************/
void CleanUpMovie(MovieInstance *theMovie)
{
if(theMovie->movie) /* if 0, this entry is unused */
{
CloseMovieFile(theMovie->resRefNum); /* We're done with the file */
CloseComponent(theMovie->movieController); /* Throw out the controller first */
theMovie->movieController = nil;
DisposeMovie(theMovie->movie); /* Toss the movie */
theMovie->movie = 0; /* Mark it as unused */
if(theMovie == activeMovie)
activeMovie=0;
DisposeWindow(theMovie->window); /* Toss the window, too */
numOpenMovies--; /* One less movie to worry about */
}
}
/**************************************************
*
* SaveTheMovie(theMovie) Saves the movie
*
***************************************************/
void SaveTheMovie(MovieInstance *theMovie)
{
theErr = UpdateMovieResource(theMovie->movie,theMovie->resRefNum,theMovie->resID,nil);
if (theErr) /* Put up a message if it didn't work */
DebugStr((StringPtr)"\pUpdateMovieResource Failed");
}
/**************************************************
*
* (FSSpec* file)
* Opens the movie specified by the Standard File Reply
*
***************************************************/
void OpenTheMovie(FSSpec* file)
{
static short wOffSet = 100; /* Used to offset the window from the last one opened */
MovieInstance *theMovie;
short movieResRefNum;
short movieResID;
Str255 movieName;
Rect dispBounds;
/* First find a space in the movieList Array */
theMovie = GetAvailMovie();
if (!theMovie)
goto bail3;
/* Now open the movie file */
if (theErr = OpenMovieFile(file, &(theMovie->resRefNum), 0))
goto bail2; /* Bail out if it didn't work */
/* Then the movie in the file */
theMovie->resID = 0;
theErr = NewMovieFromFile( &(theMovie->movie),theMovie->resRefNum,&theMovie->resID, nil,0, nil );
if(theErr != 0 || theMovie->movie == 0 ) goto bail;
/* We've got the movie, get the info we need from it */
/* First we need a bounding rectangle for it */
GetMovieBox(theMovie->movie, &dispBounds); /* Get the bounds for the movie */
OffsetRect(&dispBounds,-dispBounds.left,-dispBounds.top); /* Make top left 0,0 */
SetMovieBox(theMovie->movie, &dispBounds);
theMovie->volume = GetMovieVolume(theMovie->movie); /* Get the sound volume */
/* Create a window for the movie */
OffsetRect(&dispBounds,wOffSet,wOffSet); /* Offset the rect for where we want the window to be */
theMovie->window = (WindowPtr) NewCWindow(0L,&dispBounds,(StringPtr)file->name,0,4,(WindowPtr)-1L,1,0L);
if(theMovie->window == nil ) goto bail;
SetPort(theMovie->window); /* Play the movie in the window */
SetMovieGWorld(theMovie->movie,nil,nil);
SetMovieActive(theMovie->movie, true); /* Needs to be active to play */
GotoBeginningOfMovie(theMovie->movie);
PrerollMovie(theMovie->movie,0,0); /* Get everything ready to play */
MakeMovieControls(theMovie); /* Get a controller for the movie */
ShowWindow(theMovie->window);
MCDoAction(theMovie->movieController, mcActionSetKeysEnabled, (void *)true);
theMovie->idleCount = 8;
numOpenMovies++; /* Bump the count of open movies */
wOffSet +=16; /* Make next movie window a bit more to the lower right */
if (wOffSet > 300)
wOffSet = 100; /* But not too far */
return;
/* Cleanup if it didn't work. A nice guy would put up an alert */
bail:
CloseMovieFile(theMovie->resRefNum); /* We're done with the file */
bail2:
if(theMovie->movie)
{
DisposeMovie(theMovie->movie);
theMovie->movie = 0;
}
bail3:
SysBeep(1);
return;
}
/**************************************************
***************************************************
*
* Movie Control stuff for making and tracking the controls
*
***************************************************
***************************************************/
/**************************************************
*
* MakeMovieControls(theMovie) Puts the controls at the bottom of the window
*
***************************************************/
void MakeMovieControls(MovieInstance *theMovie)
{
OSErr theErr;
Point thePoint;
/* Get a controller */
theMovie->movieController = OpenDefaultComponent('play',0);
if(theMovie->movieController == nil) /* Did it fail? */
return;
/* Initialize it */
/* Put it in the window */
thePoint.h = (theMovie->window)->portRect.left;
thePoint.v = (theMovie->window)->portRect.top;
theErr = MCNewAttachedController(theMovie->movieController,theMovie->movie,
theMovie->window,thePoint);
MCEnableEditing(theMovie->movieController,true); /* Show the editing controls */
SetMovieWindowSize(theMovie); /* Resize the window */
/* Filter for events we want to know about */
MCSetActionFilter(theMovie->movieController,(MCActionFilter) MyPlayerFilter);
}
/**************************************************
*
* SetMovieWindowSize(theMovie)
* Makes sure the movie box top left corner is 0,0
* Adjusts the size of the window for the movie box and the controls
*
***************************************************/
void SetMovieWindowSize(MovieInstance *theMovie)
{
Rect bounds, controllerBox;
GetMovieBox(theMovie->movie,&bounds); /* We made the top left 0,0 earlier */
OffsetRect(&bounds,-bounds.left,-bounds.top); /* Make sure top left is 0,0 */
SetMovieBox(theMovie->movie, &bounds);
/* Resize the window to be big enough for the movie and the controller */
MCGetControllerBoundsRect(theMovie->movieController,&controllerBox); /* Get the controller size */
UnionRect(&bounds,&controllerBox,&bounds);
SizeWindow( theMovie->window,bounds.right,bounds.bottom,true);
}
/**************************************************
*
* MyPlayerFilter() Puts the controls at the bottom of the window
*
* Catches player events I'm interested in
*
* YOU don't have to do this filter
* I'm doing it to show how a filter works.
*
* Activate/ deactivate events are filtered so I can
* keep track of the frontmost movie
*
* The play event is used to loop the movie if the shift key is pressed
* and palindrome if control is pressed
*
***************************************************/
pascal Boolean MyPlayerFilter(MovieController pt, short *action, void *params)
{
Boolean wasHandled = false;
long loopFlag;
short mCount;
switch( *action)
{
case mcActionActivate:
DoMovieActivate(&movieList[checkMovieControllerCount]);
break;
case mcActionDeactivate:
DoMovieDeactivate(&movieList[checkMovieControllerCount]);
break;
case mcActionPlay:
loopFlag = (theModifiers & (optionKey | controlKey)) != 0; /* Option key pressed? */
theErr = MCDoAction(pt,mcActionSetLooping,(void *) loopFlag);
loopFlag = (theModifiers & controlKey) != 0; /* Control key pressed? */
theErr = MCDoAction(pt,mcActionSetLoopIsPalindrome,(void *) loopFlag);
break;
}
return(wasHandled);
}
/**************************************************
***************************************************
*
* Movie Event stuff
*
***************************************************
***************************************************/
/**************************************************
*
* CheckMovieControllers() Checks if the event is handled by any of the
* controllerss returns true if the event was handled
*
***************************************************/
Boolean CheckMovieControllers(EventRecord *theEvent)
{
short mCount;
Boolean eventHandled = false;
/* Loop through all of the movies */
for(checkMovieControllerCount = 0;checkMovieControllerCount<maxMovies;checkMovieControllerCount++)
{
if (movieList[checkMovieControllerCount].movie) {
if ( movieList[checkMovieControllerCount].idleCount-- == 0 )
MCDoAction(movieList[checkMovieControllerCount].movieController, mcActionPlay, (void *)kFix1);
if (eventHandled = MCIsPlayerEvent(movieList[checkMovieControllerCount].movieController, theEvent)) /* Was it handled? */
break; /* If so, return */
}
}
return(eventHandled);
}
/**************************************************
*
* MyMoviesTask() Calls MoviesTask and stops at the end
* This is called from the main event loop of the application
* The active movie is serviced every time to get smooth play
* The other movies are serviced by the MovieController
*
***************************************************/
void MyMoviesTask()
{
/* Sevice the activeMovie if there is one */
if(activeMovie)
MoviesTask(activeMovie->movie,1);
}
/**************************************************
*
* MovieMouseDown(theWindow, thePoint, short theModifiers)
* Mouse pressed in movie content
* I don't have anything here since the MovieController does it all for me!
*
***************************************************/
void MovieMouseDown(WindowPtr theWindow, Point thePoint, short theModifiers)
{
}
/**************************************************
*
* DoMovieUpdate()
*
* Updates the movie screen
* I don't have anything here since the MovieController does it all for me!
*
***************************************************/
void DoMovieUpdate(theMovie)
MovieInstance *theMovie;
{
}
/**************************************************
*
* DoMovieActivate(theMovie)
*
* Increases the volume of the front movie
*
***************************************************/
void DoMovieActivate(MovieInstance *theMovie)
{
/* Restore the volume in case it was reduced */
SetMovieVolume(theMovie->movie,theMovie->volume);
activeMovie = theMovie;
}
/**************************************************
*
* DoMovieDeactivate(theMovie)
*
* Reduces the volume of the movie
*
***************************************************/
void DoMovieDeactivate(MovieInstance *theMovie)
{
/* Save the volume and reduce it */
// theMovie->volume = GetMovieVolume(theMovie->movie);
SetMovieVolume(theMovie->movie,theMovie->volume/3);
activeMovie = 0; /* no active movie */
}
/**************************************************
*
* DoMovieEdit(MovieInstance *theMovie, int menuItem)
* Handles an edit event for the movie
*
***************************************************/
void DoMovieEdit(MovieInstance *theMovie, short menuItem)
{
Movie movieScrap = 0;
long offset;
Rect bounds,bounds2;
RgnHandle tempRgn;
KeyMap theKeys; /* Used to test for shift and control key */
switch (menuItem)
{
case undoItem:
MCUndo(theMovie->movieController);
SetMovieWindowSize(theMovie); /* Resize the window if needed */
break;
case cutItem:
movieScrap = MCCut(theMovie->movieController);
break;
case copyItem:
movieScrap = MCCopy(theMovie->movieController);
break;
case pasteItem:
/* First get a movie from the scrap */
movieScrap = NewMovieFromScrap(0L);
/* Beep and return if there wasn't a movie */
/* This shouldn't happen since paste is only enabled if there is a movie */
if(!movieScrap)
{
SysBeep(1);
return;
}
/* We've got a movie, now do the paste */
/* Make sure entire movie is used */
SetMovieSelection(movieScrap,0,GetMovieDuration(movieScrap));
GetMovieBox(movieScrap,&bounds2); /* Adjust the bounds box to be pasted */
OffsetRect(&bounds2,-bounds2.left,-bounds2.top); /* Make top left 0,0 */
SetMovieBox(movieScrap, &bounds2);
GetMovieBox(theMovie->movie,&bounds); /* Get the old bounds box */
/* If shift was pressed, set the clip to be the box of the original movie */
GetKeys(theKeys); /* Get what keys are presses pressed */
if ( theKeys[1]&0x01 )
{
tempRgn = NewRgn();
RectRgn(tempRgn,&bounds); /* Make a region out of the old movie box */
SetMovieSrcClipRgn(theMovie->movie,tempRgn);
DisposeRgn(tempRgn);
}
MCPaste(theMovie->movieController,movieScrap);
SetMovieWindowSize(theMovie); /* Resize the window if needed */
DisposeMovie(movieScrap); /* We're all done with the movie */
movieScrap = 0;
break;
case clearItem:
MCClear(theMovie->movieController);
break;
case selectAllItem:
{
TimeRecord tr;
tr.value.hi = tr.value.lo = 0;
tr.base = 0;
tr.scale = GetMovieTimeScale(theMovie->movie);
MCDoAction(theMovie->movieController, mcActionSetSelectionBegin, &tr);
tr.value.hi = 0;
tr.value.lo = GetMovieDuration(theMovie->movie);
tr.base = 0;
tr.scale = GetMovieTimeScale(theMovie->movie);
MCDoAction(theMovie->movieController, mcActionSetSelectionDuration, &tr);
}
break;
}
/* If we have a scrap movie, put it in the scap */
if (movieScrap)
{
theErr = PutMovieOnScrap(movieScrap,0L);
if(theErr)
DebugStr((StringPtr)"\pPutMovieOnScrap failed");
/* Now throw out the movie */
DisposeMovie(movieScrap);
}
}